﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Threading;
using application1.SqlServerConnect;
using System.Net.Sockets;
using System.IO;
using application1.Tools;

namespace application1.User
{
    class UserClass
    {

        public TcpClient client { get; set; }
        public NetworkStream NStream { get; set; }
        public DateTime LastConnTime { get; set; }
        public string DeviceNum { get; set; }
        public byte[] buffer { get; set; }
        public Thread UserThread { get; set; }
        public int ListIndexID { get; set; }
        public string DeviceId { get; set; }

        public int ReSentTimes { get; set; }
        public byte[] TempData { get; set; }


        //传感器单轮数据
        public float Tpy_float { get; set; }
        public int Tpy_Dot { get; set; }
        public float P_float { get; set; }
        public int P_Dot { get; set; }
        public float Tlk_float { get; set; }
        public float CO_float { get; set; }
        public float O2_float { get; set; }

        public bool RelayState { get; set; }    //当前继电器状态

        private static readonly object obj = new object();



        public void Close()
        {
            //br.Close();
            //br.Dispose();
            //bw.Close();
            //bw.Dispose();
            client.Close();

            NStream.Close();
            NStream.Dispose();

            //Log.Info("User", "在主函数里面Remove相关UserList，脱离的线程ID=" + UserThread.ManagedThreadId.ToString() + ";脱离的MeterIP=" + MeterIP);
            Program.UserList.Remove(this);
            //在此需要用倒叙方式删除相对应的引用
            //for (int i = Program.UserList.Count - 1; i >= 0; i--)
            //{
            //    if (Program.UserList[i].MeterIP == MeterIP)
            //    {

            //        Program.UserList.Remove(Program.UserList[i]);

            //    }
            //}

            try
            {
                UserThread.Abort(); //终止线程
                UserThread.Join();
            }
            catch (ThreadAbortException ex)
            {
                Console.WriteLine("正常捕捉到线程终止异常,线程退出完成,ThreadAbortException:" + ex.Message.ToString());
                //Log.Info("User", "线程ID=" + UserThread.ManagedThreadId.ToString() + ";正常捕捉到线程终止异常ThreadAbortException,线程退出,");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
                Console.WriteLine("线程停止失败");
            }


            //Program.UserList.RemoveAt(ListIndexID);
        }

        public UserClass(TcpClient client)
        {
            this.client = client;
            NStream = client.GetStream();

            //构造函数需要初始化默认值
            DeviceNum = "";
            LastConnTime = DateTime.Now;
            //br = new BinaryReader(NStream);
            //bw = new BinaryWriter(NStream);
        }


        public void ReciveData()
        {

            string ReceiveData = "";
            string sql = "";
            RelayState = false;
            DeviceId = "-1";

            //温度传感器滑动变化 每次变化要大于0.5°才行
            float[] TemperatureFIFO = { -100, -100, -100, -100, -100 };
            float[] PressureFIFO = { -100, -100, -100, -100, -100 };
            float[] O2FIFO = { -100, -100, -100, -100, -100 };
            if (NStream.CanRead)
            {
                buffer = new byte[1024];
                int count = 0;
                int SentTimes = 0;
                
                int IntPressure = 0;
                int PressureDot = 0;
                byte[] COByte4 = { 0x0, 0x0, 0x0, 0x0 };
                byte[] O2Byte4 = { 0x0, 0x0, 0x0, 0x0 };
                byte[] TlkByte4 = { 0x0, 0x0, 0x0, 0x0 };
                bool ready = false;
                string StateCode = "";    //设置状态机   ""
                
                do
                {
                    try
                    {

                        count = NStream.Read(buffer, 0, 1024);
                        ReceiveData = Encoding.Default.GetString(buffer, 0, count).Trim();
                        Console.WriteLine(ReceiveData + ",ip=" + GetRemoteIPAndPort(client));

                        if (ReceiveData.Contains("TEST"))
                        {
                            DeviceNum = ReceiveData;
                            NStream.Flush();

                            //找出对应的DeviceId
                            sql = "select DeviceId from t_d_Device where TcpHead='" + ReceiveData + "'";
                            try
                            {
                                BaseDao tempdao = new BaseDao();
                                DeviceId = tempdao.GetList(sql, new string[] { "DeviceId" })[0]["DeviceId"].ToString();
                            }
                            catch (Exception)
                            {

                                Close();
                            }

                            //if (ReceiveData == "TEST111")
                            //{
                            //    ready = true;
                            //}

                            ready = true;
                            Log.Info("RelayOff", "单片机重新连接");
                        }

                        //Thread.Sleep(2000);
                        LastConnTime = DateTime.Now;

                        if (ready == true)
                        {
                            switch (StateCode)
                            {
                                case "":    //表明为空状态
                                            //下面获取温度
                                    CheckTemperature();
                                    StateCode = "Temperature";
                                    break;

                                case "Temperature":
                                    //表明接收到温度信息
                                    byte[] RecTempByte = buffer.Skip(0).Take(count).ToArray();
                                    if (CheckGetTemperature(RecTempByte))
                                    {
                                        //正确
                                        Console.WriteLine("接收到温度数据，验证成功:" + CRC.ToHexString(RecTempByte));
                                        //转换成温度数据
                                        Tpy_float = 256 * RecTempByte[3] + RecTempByte[4];

                                        //sql = "insert into t_d_Temperature (temperature,UpdateTime) values (" + Tpy_float.ToString() + ",'" + DateTime.Now.ToString() + "')";
                                        //BaseDao.execute(sql);

                                        Thread.Sleep(200);

                                        //下面获取温度小数点
                                        StateCode = "TemperatureDot";
                                        CheckTemperatureDot();
                                    }
                                    else
                                    {
                                        Console.WriteLine("此刻的温度数据验证失败");
                                        CheckTemperature();
                                        StateCode = "Temperature";
                                        ready = true;
                                    }
                                    break;
                                case "TemperatureDot":
                                    //表明接收到温度信息
                                    byte[] RecTempDotByte = buffer.Skip(0).Take(count).ToArray();
                                    if (CheckGetTemperature(RecTempDotByte))
                                    {
                                        //正确
                                        Console.WriteLine("接收到温度小数点数据，验证成功:" + CRC.ToHexString(RecTempDotByte));
                                        //转换成小数点个数
                                        Tpy_Dot = 256 * RecTempDotByte[3] + RecTempDotByte[4];

                                        Console.WriteLine("设备号" + DeviceId.ToString() + ",温度:" + Tpy_float.ToString() + ",小数点:" + Tpy_Dot.ToString());
                                        Tpy_float = (float)(Tpy_float / Math.Pow(10, Tpy_Dot));

                                        //sql = "insert into t_d_Temperature (temperature,UpdateTime) values (" + Tpy_float.ToString() + ",'" + DateTime.Now.ToString() + "')";
                                        //BaseDao.execute(sql);
                                        Thread.Sleep(200);

                                        //下面获取压力
                                        StateCode = "Pressure";
                                        CheckPressure();
                                    }
                                    else
                                    {
                                        //验证错误 返回上一个状态机
                                        Console.WriteLine("此刻的温度小数点数据验证失败");
                                        CheckTemperature();
                                        StateCode = "Temperature";
                                        ready = true;
                                    }
                                    break;

                                case "Pressure":
                                    byte[] RecPresByte = buffer.Skip(0).Take(count).ToArray();
                                    if (CheckGetPressure(RecPresByte))
                                    {
                                        //正确
                                        Console.WriteLine("接收到压力数据，验证成功:" + CRC.ToHexString(RecPresByte));
                                        //转换成温度数据
                                        UInt16 UPressure = 0;
                                        UPressure = (UInt16)((UInt16)(RecPresByte[3] << 8) + RecPresByte[4]);

                                        IntPressure = (Int16)UPressure;
                                        //sql = "insert into t_d_Pressure (Pressure,UpdateTime) values (" + IntPressure.ToString() + ",'" + DateTime.Now.ToString() + "')";
                                        //BaseDao.execute(sql);
                                        Thread.Sleep(200);

                                        //下面获取压力单位
                                        StateCode = "PressureDot";
                                        CheckPressureDot();

                                        //CheckPressure();
                                    }
                                    else
                                    {
                                        //验证错误 返回上一个状态机
                                        Console.WriteLine("此刻的压力数据验证失败");
                                        CheckTemperature();
                                        StateCode = "Temperature";
                                        ready = true;
                                    }
                                    break;

                                case "PressureUnit":
                                    byte[] RecPresUnitByte = buffer.Skip(0).Take(count).ToArray();
                                    if (CheckGetPressure(RecPresUnitByte))
                                    {
                                        //正确
                                        Console.WriteLine("接收到压力单位数据，验证成功:" + CRC.ToHexString(RecPresUnitByte));
                                        //转换成温度数据
                                        int IntPressureUnit = 256 * RecPresUnitByte[3] + RecPresUnitByte[4];
                                        //sql = "insert into t_d_Pressure (Pressure,UpdateTime) values (" + IntPressureUnit.ToString() + ",'" + DateTime.Now.ToString() + "')";
                                        //BaseDao.execute(sql);
                                        Thread.Sleep(200);

                                        //这一轮完毕
                                        StateCode = "PressureDot";
                                        CheckPressureDot();
                                        

                                        //CheckPressure();
                                    }
                                    else
                                    {
                                        //验证错误 返回上一个状态机
                                        Console.WriteLine("此刻的压力单位数据验证失败");
                                        StateCode = "";
                                        ready = false;
                                    }
                                    break;

                                case "PressureDot":
                                    byte[] RecPresDotByte = buffer.Skip(0).Take(count).ToArray();
                                    if (CheckGetPressure(RecPresDotByte))
                                    {
                                        //正确
                                        Console.WriteLine("接收到压力小数点数据，验证成功:" + CRC.ToHexString(RecPresDotByte));
                                        //转换成温度数据
                                        PressureDot = 256 * RecPresDotByte[3] + RecPresDotByte[4];
                                        P_float= (float)(IntPressure / Math.Pow(10, PressureDot));
                                        sql = "insert into t_d_Pressure (Pressure,UpdateTime) values (" + P_float.ToString("f4") + ",'" + DateTime.Now.ToString() + "')";
                                        //BaseDao.execute(sql);
                                        Thread.Sleep(200);

                                        //下次检测一氧化碳12字节
                                        StateCode = "CO_12";
                                        CheckCO();

                                        //CheckPressure();
                                    }
                                    else
                                    {
                                        //验证错误 返回上一个状态机
                                        Console.WriteLine("此刻的压力单位数据验证失败");
                                        CheckTemperature();
                                        StateCode = "Temperature";
                                        ready = true;
                                    }
                                    break;

                                case "CO_12":
                                    byte[] RecCO12Byte = buffer.Skip(0).Take(count).ToArray();
                                    if (CheckGetGas(RecCO12Byte))
                                    {
                                        Console.WriteLine("接收到一氧化碳12字节数据，验证成功:" + CRC.ToHexString(RecCO12Byte));
                                        COByte4[0] = RecCO12Byte[4];
                                        COByte4[1] = RecCO12Byte[3];
                                        Thread.Sleep(200);

                                        ////下次检测一氧化碳34字节
                                        StateCode = "CO_34";
                                        CheckCO34();

                                    }
                                    else
                                    {
                                        //验证错误 返回上一个状态机
                                        Console.WriteLine("此刻的一氧化碳12字节验证失败");
                                        CheckTemperature();
                                        StateCode = "Temperature";
                                        ready = true;
                                    }
                                    break;

                                case "CO_34":
                                    byte[] RecCO34Byte = buffer.Skip(0).Take(count).ToArray();
                                    if (CheckGetGas(RecCO34Byte))
                                    {
                                        Console.WriteLine("接收到一氧化碳34字节数据，验证成功:" + CRC.ToHexString(RecCO34Byte));
                                        COByte4[2] = RecCO34Byte[4];
                                        COByte4[3] = RecCO34Byte[3];
                                        Thread.Sleep(200);

                                        //转化为float
                                        CO_float = BitConverter.ToSingle(COByte4, 0);
                                        Console.WriteLine("转化的一氧化碳数值为" + CO_float.ToString("f2"));
                                        sql = "insert into t_d_CO (CO,UpdateTime) values (" + CO_float.ToString("f2") + ",'" + DateTime.Now.ToString() + "')";
                                        //BaseDao.execute(sql);
                                        //Thread.Sleep(500);
                                        ////下次检测氧气12字节
                                        StateCode = "O2_12";
                                        CheckO2_12();

                                    }
                                    else
                                    {
                                        //验证错误 返回上一个状态机
                                        Console.WriteLine("此刻的一氧化碳34字节验证失败");
                                        CheckTemperature();
                                        StateCode = "Temperature";
                                        ready = true;
                                    }
                                    break;

                                case "O2_12":
                                    byte[] RecO2_12Byte = buffer.Skip(0).Take(count).ToArray();
                                    if (CheckGetGas(RecO2_12Byte))
                                    {
                                        Console.WriteLine("接收到氧气12字节数据，验证成功:" + CRC.ToHexString(RecO2_12Byte));
                                        O2Byte4[0] = RecO2_12Byte[4];
                                        O2Byte4[1] = RecO2_12Byte[3];

                                        Thread.Sleep(200);
                                        ////下次检测氧气12字节
                                        StateCode = "O2_34";
                                        CheckO2_34();

                                    }
                                    else
                                    {
                                        //验证错误 返回上一个状态机
                                        Console.WriteLine("此刻的氧气12字节验证失败");
                                        CheckTemperature();
                                        StateCode = "Temperature";
                                        ready = true;
                                    }
                                    break;

                                case "O2_34":
                                    byte[] RecO2_34Byte = buffer.Skip(0).Take(count).ToArray();
                                    if (CheckGetGas(RecO2_34Byte))
                                    {
                                        Console.WriteLine("接收到一氧化碳34字节数据，验证成功:" + CRC.ToHexString(RecO2_34Byte));
                                        O2Byte4[2] = RecO2_34Byte[4];
                                        O2Byte4[3] = RecO2_34Byte[3];

                                        //转化为float
                                        O2_float = BitConverter.ToSingle(O2Byte4, 0);
                                        Console.WriteLine("转化的氧气数值为" + O2_float.ToString("f2"));
                                        sql = "insert into t_d_O2 (O2,UpdateTime) values (" + O2_float.ToString("f2") + ",'" + DateTime.Now.ToString() + "')";
                                        //BaseDao.execute(sql);
                                        Thread.Sleep(200);
                                        //本轮结束
                                        StateCode = "Tlk_12";
                                        CheckTlk_12();

                                    }
                                    else
                                    {
                                        //验证错误 返回上一个状态机
                                        Console.WriteLine("此刻的氧气34节验证失败");
                                        CheckTemperature();
                                        StateCode = "Temperature";
                                        ready = true;
                                    }
                                    break;

                                case "Tlk_12":
                                    byte[] RecTlk_12Byte = buffer.Skip(0).Take(count).ToArray();
                                    if (CheckGetGas(RecTlk_12Byte))
                                    {
                                        Console.WriteLine("接收到冷空气12字节数据，验证成功:" + CRC.ToHexString(RecTlk_12Byte));
                                        TlkByte4[0] = RecTlk_12Byte[4];
                                        TlkByte4[1] = RecTlk_12Byte[3];

                                        //转化为float
                                        //O2_float = BitConverter.ToSingle(O2Byte4, 0);
                                        //Console.WriteLine("转化的氧气数值为" + O2_float.ToString("f2"));
                                        //sql = "insert into t_d_O2 (O2,UpdateTime) values (" + O2_float.ToString("f2") + ",'" + DateTime.Now.ToString() + "')";
                                        //BaseDao.execute(sql);
                                        Thread.Sleep(200);
                                        //本轮结束
                                        StateCode = "Tlk_34";
                                        CheckTlk_34();

                                    }
                                    else
                                    {
                                        //验证错误 返回上一个状态机
                                        Console.WriteLine("此刻的冷空气12字节验证失败");
                                        CheckTemperature();
                                        StateCode = "Temperature";
                                        ready = true;
                                    }
                                    break;

                                case "Tlk_34":
                                    byte[] RecTlk_34Byte = buffer.Skip(0).Take(count).ToArray();
                                    if (CheckGetGas(RecTlk_34Byte))
                                    {
                                        Console.WriteLine("接收到冷空气34字节数据，验证成功:" + CRC.ToHexString(RecTlk_34Byte));
                                        TlkByte4[2] = RecTlk_34Byte[4];
                                        TlkByte4[3] = RecTlk_34Byte[3];

                                        //转化为float
                                        Tlk_float = BitConverter.ToSingle(TlkByte4, 0);
                                        Console.WriteLine("转化的冷空气温度数值为" + Tlk_float.ToString("f2"));

                                        if (RelayState == false)    //关闭状态下
                                        {
                                            if(Tpy_float>130&& P_float > 0.4)
                                            {
                                                //这里开继电器操作
                                                Thread.Sleep(200);
                                                RelayOn();
                                                StateCode = "RelayOn";
                                                Log.Info("Relay", "继电器变化为开");
                                            }
                                            else
                                            {
                                                //关继电器操作
                                                //xxxxxxxxx
                                                Thread.Sleep(200);
                                                RelayOff();
                                                StateCode = "RelayOff";
                                            }
                                        }
                                        else
                                        {
                                            if (Tpy_float < 120 && P_float < 0.4)
                                            {
                                                //关继电器操作
                                                //xxxxxxxxx
                                                Thread.Sleep(200);
                                                RelayOff();
                                                StateCode = "RelayOff";
                                                Log.Info("Relay", "继电器变化为关");
                                            }
                                            else
                                            {
                                                //这里开继电器操作
                                                Thread.Sleep(200);
                                                RelayOn();
                                                StateCode = "RelayOn";
                                            }
                                        }


                                        /*

                                        //在这里判断模态
                                        //首先完温度队列左移
                                        for (int i = 0; i < 4; i++)
                                        {
                                            TemperatureFIFO[i] = TemperatureFIFO[i + 1];
                                        }
                                        TemperatureFIFO[4] = Tpy_float;
                                        //完成压力队列左移
                                        for (int i = 0; i < 4; i++)
                                        {
                                            PressureFIFO[i] = PressureFIFO[i + 1];
                                        }
                                        PressureFIFO[4] = P_float;
                                        //完成氧气队列左移
                                        for (int i = 0; i < 4; i++)
                                        {
                                            O2FIFO[i] = O2FIFO[i + 1];
                                        }
                                        O2FIFO[4] = O2_float;

                                        if (RelayState == false)    //关闭状态下
                                        {
                                            
                                            //然后看看温度队列是不是递增
                                            bool Tdt = true;
                                            for (int i = 0; i < 4; i++)
                                            {
                                                if (TemperatureFIFO[i + 1] <= TemperatureFIFO[i])
                                                {
                                                    Tdt = false;
                                                }
                                            }
                                            //看看压力队列是不是非减
                                            bool Pdt = true;
                                            for (int i = 0; i < 4; i++)
                                            {
                                                if (PressureFIFO[i + 1] < PressureFIFO[i])
                                                {
                                                    Pdt = false;
                                                }
                                            }
                                            Console.WriteLine("Tdt="+Tdt.ToString()+ ",Pdt="+Pdt.ToString()+",Tpy="+Tpy_float.ToString());
                                            Log.Info("RelayOff", "Tdt=" + Tdt.ToString() + ",Pdt=" + Pdt.ToString() + ",Tpy=" + Tpy_float.ToString() + ",T0=" + TemperatureFIFO[0].ToString("f2") + ",T1=" + TemperatureFIFO[1].ToString("f2") + ",T2=" + TemperatureFIFO[2].ToString("f2") + ",T3=" + TemperatureFIFO[3].ToString("f2") + ",T4=" + TemperatureFIFO[4].ToString("f2"));
                                            if (Tdt==true && Pdt==true && Tpy_float > 120 && (TemperatureFIFO[4] - TemperatureFIFO[0]) > 5)
                                            {
                                                //(TemperatureFIFO[4] - TemperatureFIFO[0]) > 5是为了避免抖动的情况
                                                
                                                //这里开继电器操作
                                                Thread.Sleep(200);
                                                RelayOn();
                                                StateCode = "RelayOn";

                                            }
                                            else
                                            {
                                                //关继电器操作
                                                //xxxxxxxxx
                                                Thread.Sleep(200);
                                                RelayOff();
                                                StateCode = "RelayOff";

                                            }

                                        }
                                        else    //继电器打开状态下
                                        {
                                            //然后看看温度队列是不是递减
                                            bool Tdt = true;
                                            for (int i = 0; i < 4; i++)
                                            {
                                                if (TemperatureFIFO[i + 1] >= TemperatureFIFO[i])
                                                {
                                                    Tdt = false;
                                                }
                                            }
                                            //看看压力队列是不是非增
                                            bool Pdt = true;
                                            for (int i = 0; i < 4; i++)
                                            {
                                                if (PressureFIFO[i + 1] > PressureFIFO[i])
                                                {
                                                    Pdt = false;
                                                }
                                            }
                                            //看看氧气队列是不是非减
                                            bool O2dt = true;
                                            for (int i = 0; i < 4; i++)
                                            {
                                                if (O2FIFO[i + 1] < O2FIFO[i])
                                                {
                                                    O2dt = false;
                                                }
                                            }
                                            Console.WriteLine("Tdt=" + Tdt.ToString() + ",Pdt=" + Pdt.ToString() + ",O2dt=" + O2dt.ToString());
                                            Log.Info("RelayOn", "Tdt=" + Tdt.ToString() + ",Pdt=" + Pdt.ToString() + ",O2dt=" + O2dt.ToString() + ",O2=" + O2FIFO[4].ToString("f2") + ",T0=" + TemperatureFIFO[0].ToString("f2") + ",T1=" + TemperatureFIFO[1].ToString("f2") + ",T2=" + TemperatureFIFO[2].ToString("f2") + ",T3=" + TemperatureFIFO[3].ToString("f2") + ",T4=" + TemperatureFIFO[4].ToString("f2"));

                                            if (Tdt==true && Pdt==true && O2dt==true && O2FIFO[4] > 16 && (TemperatureFIFO[4] - TemperatureFIFO[0]) < -1.5)
                                            {
                                                //关继电器操作
                                                //xxxxxxxxx
                                                Thread.Sleep(200);
                                                RelayOff();
                                                StateCode = "RelayOff";
                                            }
                                            else
                                            {
                                                //(TemperatureFIFO[4] - TemperatureFIFO[0]) < -1.5 为了去除抖动
                                                //这里开继电器操作
                                                Thread.Sleep(200);
                                                RelayOn();
                                                StateCode = "RelayOn";
                                            }

                                        }

                                        */

                                    }
                                    else
                                    {
                                        //验证错误 返回上一个状态机
                                        Console.WriteLine("此刻的冷空气34节验证失败");
                                        CheckTemperature();
                                        StateCode = "Temperature";
                                        ready = true;
                                    }
                                    break;

                                case "RelayOn":
                                    byte[] RelayOn_Byte = buffer.Skip(0).Take(count).ToArray();
                                    if (CheckGetRelay(RelayOn_Byte))
                                    {
                                        Console.WriteLine("接收到继电器打开数据，验证成功:" + CRC.ToHexString(RelayOn_Byte));
                                        RelayState = true;
                                        //计算效率
                                        float effi = CalcEfficiency(O2_float, CO_float, Tpy_float, Tlk_float);
                                        Console.WriteLine("效率为：" + effi.ToString("f2"));

                                        SentTimes++;

                                        sql = "insert into t_d_SensorData (CO,O2,Pressure,Tpy,Tlk,UpdateTime,Efficiency,Relay,DeviceId) values (" + CO_float.ToString("f2") + "," + O2_float.ToString("f2") + "," + P_float.ToString("f2") + "," + Tpy_float.ToString("f2") + "," + Tlk_float.ToString("f2") + ",'" + DateTime.Now.ToString() + "'," + effi.ToString("f2") + ",1," + DeviceId + ")";
                                        Console.WriteLine("SentTimes=" + SentTimes.ToString());
                                        if (effi > 0)
                                        {
                                            if (P_float > 0.2)
                                            {
                                                //要看压力有了才能入库
                                                BaseDao.execute(sql);
                                                Console.WriteLine("写入数据库");
                                            }


                                        }
                                        else if (SentTimes > 4)
                                        {
                                            if (O2_float < 0 || Tlk_float > 60 || Tlk_float < -10 || Tpy_float-Tlk_float<-2)
                                            {
                                                SentTimes--;
                                                Log.Info("dataErr", "O2="+O2_float.ToString()+",Tpy="+Tpy_float.ToString()+",Tlk="+Tlk_float.ToString());
                                                Console.WriteLine("监测到采集数据有误");
                                            }
                                            else
                                            {
                                                SentTimes = 0;
                                                if(P_float==0 && Tpy_float > 130)
                                                {
                                                    //这个时候表明是错误数据，不要入库
                                                }
                                                else
                                                {
                                                    BaseDao.execute(sql);
                                                    Console.WriteLine("写入数据库");
                                                }

                                            }
                                        }

                                        Thread.Sleep(1000);
                                        //本轮结束  开启循环
                                        CheckTemperature();
                                        StateCode = "Temperature";

                                    }
                                    else
                                    {
                                        //验证错误 返回上一个状态机
                                        Console.WriteLine("此刻的继电器打开验证失败");
                                        CheckTemperature();
                                        StateCode = "Temperature";
                                        ready = true;
                                    }
                                    break;

                                case "RelayOff":
                                    byte[] RelayOff_Byte = buffer.Skip(0).Take(count).ToArray();
                                    if (CheckGetRelay(RelayOff_Byte))
                                    {
                                        Console.WriteLine("接收到继电器关闭数据，验证成功:" + CRC.ToHexString(RelayOff_Byte));
                                        RelayState = false;
                                        //计算效率
                                        float effi = CalcEfficiency(O2_float, CO_float, Tpy_float, Tlk_float);
                                        Console.WriteLine("效率为：" + effi.ToString("f2"));

                                        SentTimes++;

                                        sql = "insert into t_d_SensorData (CO,O2,Pressure,Tpy,Tlk,UpdateTime,Efficiency,Relay,DeviceId) values (" + CO_float.ToString("f2") + "," + O2_float.ToString("f2") + "," + P_float.ToString("f2") + "," + Tpy_float.ToString("f2") + "," + Tlk_float.ToString("f2") + ",'" + DateTime.Now.ToString() + "'," + effi.ToString("f2") + ",0," + DeviceId + ")";
                                        Console.WriteLine("SentTimes=" + SentTimes.ToString()+",DeviceId="+DeviceId);
                                        if (effi > 0)
                                        {
                                            if (P_float > 0.2)
                                            {
                                                //要看压力有了才能入库
                                                BaseDao.execute(sql);
                                                Console.WriteLine("写入数据库");
                                            }
                                        }
                                        else if (SentTimes > 4)
                                        {
                                            if (O2_float < 0 || Tlk_float > 60 || Tlk_float < -10 || Tpy_float - Tlk_float < -2)
                                            {
                                                SentTimes--;
                                                Log.Info("dataErr", "O2=" + O2_float.ToString() + ",Tpy=" + Tpy_float.ToString() + ",Tlk=" + Tlk_float.ToString());
                                                Console.WriteLine("监测到采集数据有误");
                                            }
                                            else
                                            {
                                                SentTimes = 0;
                                                if (P_float == 0 && Tpy_float > 130)
                                                {
                                                    //这个时候表明是错误数据，不要入库
                                                }
                                                else
                                                {
                                                    BaseDao.execute(sql);
                                                    Console.WriteLine("写入数据库");
                                                }
                                            }
                                        }

                                        Thread.Sleep(1000);
                                        //本轮结束  开启循环
                                        CheckTemperature();
                                        StateCode = "Temperature";

                                    }
                                    else
                                    {
                                        //验证错误 返回上一个状态机
                                        Console.WriteLine("此刻的继电器关闭验证失败");
                                        CheckTemperature();
                                        StateCode = "Temperature";
                                        ready = true;
                                    }
                                    break;
                            }
                        }
                        //下面开始发送温度查询数据
                    }
                    catch (ThreadAbortException ex)
                    {
                        Console.WriteLine("捕捉线程终止异常,ThreadAbortException:" + ex.Message.ToString());
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message.ToString());
                        //Log.Info("User", "处理ReceiveData的时候抛出catch，ex=" + ex.Message.ToString() + ",处理后的数据为:" + ReceiveData);
                        Close();
                        break;
                    }
                    NStream.Flush();

                } while (client.IsOnline());
            }
            client.Close();
            NStream.Close();
            NStream.Dispose();
            Program.UserList.Remove(this);
            Console.WriteLine("线程退出");
            //Log.Info("User", "线程ID=" + UserThread.ManagedThreadId.ToString() + ";线程最后退出");
        }



        public void SendData(String data)
        {
            if (NStream.CanWrite)
            {
                byte[] WriteBuffer = Encoding.Default.GetBytes(data);
                NStream.Write(WriteBuffer, 0, WriteBuffer.Length);
                //Console.WriteLine("向" + MeterIP + "发送数据完成");
                Console.WriteLine("发送数据为:" + data);
            }
            else
            {
                Console.WriteLine("Sorry.  You cannot write to this NetworkStream.");
                //Log.Error("SendDataError", "MeterIP=" + MeterIP + "，向其发送数据失败失败");
            }
        }

        public void SendDataByte(byte[] buffer)
        {
            try
            {
                if (NStream.CanWrite)
                {
                
                    NStream.Write(buffer, 0, buffer.Length);
                    //Console.WriteLine("向" + MeterIP + "发送数据完成");
                    Console.WriteLine("发送数据为:" + CRC.ToHexString(buffer));
                    TempData = buffer;
                }
                else
                {
                    Console.WriteLine("Sorry.  You cannot write to this NetworkStream.");
                    Log.Error("SendDataError", "向其发送数据失败");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
                Log.Error("SendDataError", ex.Message.ToString());
                Close();
                
            }

        }

        public string GetRemoteIPAndPort(TcpClient cln)
        {

            IPEndPoint ip = (IPEndPoint)cln.Client.RemoteEndPoint;
            string ipaddress = ip.Address.ToString();
            string port = ip.Port.ToString();
            return ipaddress + ":" + port;
        }

        /// <summary>
        /// 查温度传感器
        /// </summary>
        public void CheckTemperature()
        {
            //byte[] temp1 = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 };        //测试数据
            byte[] temp1 = { 0x02, 0x03, 0x00, 0x04, 0x00, 0x01 };
            string CRCStr=CRC.ToModbusCRC16(temp1, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] data = temp1.Concat(CRCByte).ToArray();
            Console.WriteLine("发送温度");
            SendDataByte(data);
           
        }

        public void CheckTemperatureDot()
        {

            byte[] temp1 = { 0x02, 0x03, 0x00, 0x03, 0x00, 0x01 };
            string CRCStr = CRC.ToModbusCRC16(temp1, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] data = temp1.Concat(CRCByte).ToArray();
            Console.WriteLine("发送温度小数点");
            SendDataByte(data);
        }

        public bool CheckGetTemperature(byte[] GetData)
        {
            ReSentTimes = 0;
            Console.WriteLine(CRC.ToHexString(GetData));
            //byte[] GetData = CRC.StringToHexByte(Data);
            if(GetData.Length != 7)
            {
                Console.WriteLine("长度不等于7");
                return false;
            }
            byte[] PreVerifyDataByte = GetData.Skip(0).Take(5).ToArray();
            string CRCStr = CRC.ToModbusCRC16(PreVerifyDataByte, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] VerifyDataByte= PreVerifyDataByte.Concat(CRCByte).ToArray();
            //string VerifyDataStr = CRC.ToHexString(VerifyDataByte);
            
            if (CRC.ByteEquals(GetData, VerifyDataByte))
            {
                //证明验证成功
                

                //最后返回true
                return true;
            }
            else
            {


                return false;
            }
        }

        public void CheckPressure()
        {
            //byte[] temp1 = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 };        //测试数据
            

            byte[] temp1 = { 0x01, 0x03, 0x00, 0x04, 0x00, 0x01 };
            string CRCStr = CRC.ToModbusCRC16(temp1, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] data = temp1.Concat(CRCByte).ToArray();
            Console.WriteLine("发送压力");
            SendDataByte(data);
        }


        public void CheckPressureUnit()
        {
            //byte[] temp1 = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 };        //测试数据


            byte[] temp1 = { 0x01, 0x03, 0x00, 0x02, 0x00, 0x01 };
            string CRCStr = CRC.ToModbusCRC16(temp1, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] data = temp1.Concat(CRCByte).ToArray();
            Console.WriteLine("发送压力单位");
            SendDataByte(data);
        }

        public void CheckPressureDot()
        {
            //byte[] temp1 = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 };        //测试数据


            byte[] temp1 = { 0x01, 0x03, 0x00, 0x03, 0x00, 0x01 };
            string CRCStr = CRC.ToModbusCRC16(temp1, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] data = temp1.Concat(CRCByte).ToArray();
            Console.WriteLine("发送压力小数点");
            SendDataByte(data);
        }

        public bool CheckGetPressure(byte[] GetData)
        {
            ReSentTimes = 0;
            //byte[] GetData = CRC.StringToHexByte(Data);
            if (GetData.Length != 7)
            {
                return false;
            }
            byte[] PreVerifyDataByte = GetData.Skip(0).Take(5).ToArray();
            string CRCStr = CRC.ToModbusCRC16(PreVerifyDataByte, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] VerifyDataByte = PreVerifyDataByte.Concat(CRCByte).ToArray();
            //string VerifyDataStr = CRC.ToHexString(VerifyDataByte);

            if (CRC.ByteEquals(GetData, VerifyDataByte))
            {
                //证明验证成功


                //最后返回true
                return true;
            }
            else
            {


                return false;
            }
        }

        public void CheckCO()   //检查一氧化碳
        {
            //byte[] temp1 = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 };        //测试数据


            byte[] temp1 = { 0x05, 0x03, 0x02, 0x4e, 0x00, 0x01 };
            string CRCStr = CRC.ToModbusCRC16(temp1, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] data = temp1.Concat(CRCByte).ToArray();
            Console.WriteLine("发送CO前2字节");
            SendDataByte(data);
        }
        public void CheckCO34()   //检查一氧化碳
        {
            //byte[] temp1 = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 };        //测试数据


            byte[] temp1 = { 0x05, 0x03, 0x02, 0x4f, 0x00, 0x01 };
            string CRCStr = CRC.ToModbusCRC16(temp1, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] data = temp1.Concat(CRCByte).ToArray();
            Console.WriteLine("发送CO第34字节");
            SendDataByte(data);
        }

        public void CheckO2_12()   //检查氧气12字节
        {
            byte[] temp1 = { 0x05, 0x03, 0x04, 0x4e, 0x00, 0x01 };
            if (DeviceId != "1")
            {
                temp1[2] = 0x01;
            }
            string CRCStr = CRC.ToModbusCRC16(temp1, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] data = temp1.Concat(CRCByte).ToArray();
            Console.WriteLine("发送O2第12字节");
            SendDataByte(data);
        }

        public void CheckO2_34()   //检查氧气34字节
        {
            byte[] temp1 = { 0x05, 0x03, 0x04, 0x4f, 0x00, 0x01 };
            if (DeviceId != "1")
            {
                temp1[2] = 0x01;
            }
            string CRCStr = CRC.ToModbusCRC16(temp1, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] data = temp1.Concat(CRCByte).ToArray();
            Console.WriteLine("发送O2第34字节");
            SendDataByte(data);
        }

        public void CheckTlk_12()   //检查冷空气
        {
            byte[] temp1 = { 0x05, 0x03, 0x00, 0x1f, 0x00, 0x01 };
            string CRCStr = CRC.ToModbusCRC16(temp1, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] data = temp1.Concat(CRCByte).ToArray();
            Console.WriteLine("发送Tlk第12字节");
            SendDataByte(data);
        }
        public void CheckTlk_34()   //检查冷空气
        {
            byte[] temp1 = { 0x05, 0x03, 0x00, 0x20, 0x00, 0x01 };
            string CRCStr = CRC.ToModbusCRC16(temp1, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] data = temp1.Concat(CRCByte).ToArray();
            Console.WriteLine("发送Tlk第34字节");
            SendDataByte(data);
        }

        public bool CheckGetGas(byte[] GetData)
        {
            ReSentTimes = 0;
            //byte[] GetData = CRC.StringToHexByte(Data);
            if (GetData.Length != 7)
            {
                return false;
            }
            byte[] PreVerifyDataByte = GetData.Skip(0).Take(5).ToArray();
            string CRCStr = CRC.ToModbusCRC16(PreVerifyDataByte, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] VerifyDataByte = PreVerifyDataByte.Concat(CRCByte).ToArray();
            //string VerifyDataStr = CRC.ToHexString(VerifyDataByte);

            if (CRC.ByteEquals(GetData, VerifyDataByte))
            {
                //证明验证成功


                //最后返回true
                return true;
            }
            else
            {


                return false;
            }
        }


        public void RelayOn()
        {
            byte[] temp1 = { 0x11, 0x05, 0x00, 0x01, 0xFF, 0x00,0xDF,0x6A };
            Console.WriteLine("发送闭合继电器");
            SendDataByte(temp1);
        }

        public void RelayOff()
        {
            byte[] temp1 = { 0x11, 0x05, 0x00, 0x01, 0x00, 0x00, 0x9E, 0x9A };
            Console.WriteLine("发送断开继电器");
            SendDataByte(temp1);
        }


        public bool CheckGetRelay(byte[] GetData)
        {
            ReSentTimes = 0;
            //byte[] GetData = CRC.StringToHexByte(Data);
            if (GetData.Length != 8)
            {
                return false;
            }
            byte[] PreVerifyDataByte = GetData.Skip(0).Take(6).ToArray();
            string CRCStr = CRC.ToModbusCRC16(PreVerifyDataByte, true);
            byte[] CRCByte = CRC.StringToHexByte(CRCStr);
            byte[] VerifyDataByte = PreVerifyDataByte.Concat(CRCByte).ToArray();
            //string VerifyDataStr = CRC.ToHexString(VerifyDataByte);

            if (CRC.ByteEquals(GetData, VerifyDataByte))
            {
                //证明验证成功


                //最后返回true
                return true;
            }
            else
            {


                return false;
            }
        }



        /// <summary>
        /// 天然气锅炉计算公式
        /// </summary>
        /// <param name="O2"></param>
        /// <param name="CO"></param>
        /// <param name="Tpy"></param>
        /// <param name="Tlk"></param>
        /// <returns></returns>
        public float CalcEfficiency(float O2,float CO,float Tpy,float Tlk)
        {
            if (O2 > 10 || O2<0 || Tlk>60 || Tlk<-10)
            {
                return 0;
            }
            if(O2==0 && Tpy < 80)
            {
                return 0;
            }
            if (Tpy - Tlk < -2)
            {
                return 0;
            }

            float m = 0.5f;
            float n = 3.45f;
            float apy = 0f;
            float q2 = 0; 
            float q3 = 0.2f;
            float q4 = 0f;
            float q5 = 2.9f;

            apy = 21 / (21 - O2 - 0);
            q2 = (m + n * apy) * ((Tpy - Tlk) / 100);

            return 100 - (q2 + q3 + q4 + q5);

        }




    }
    public static class TcpClientEx
    {
        public static bool IsOnline(this TcpClient c)
        {
            return !((c.Client.Poll(1000, SelectMode.SelectRead) && (c.Client.Available == 0)) || !c.Client.Connected);
        }
    }
}
